package com.manager
{
	import com.game.events.GameEvent;
	import com.game.events.GameEventDispatcher;
	import com.game.events.GameEventType;
	import com.game.render.RenderManager;
	import com.update.Update;
	import com.update.interfaces.IUpdate;

	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.utils.getTimer;

	/**
	 * @author hyy
	 * 创建时间：2013-5-9 下午5:35:46
	 *
	 */
	public class GameManager
	{
		/**
		 * 消息机制
		 */
		private var notify : GameEventDispatcher;

		private static var instance : GameManager;

		/**
		 * 渲染管理器 
		 */
		private var renderMgr : RenderManager;

		/**
		 * 场景容器
		 */
		private var container : DisplayObjectContainer;

		/**
		 * 高,中,低 3个级别的更新队列
		 */
		private var highUpdatables : Array = [];

		private var middenUpdatables : Array = [];

		private var lowUpdatables : Array = [];

		/**
		 * 游戏时间
		 */
		private var runTime : int;

		/**
		 * 当前可更新时间
		 */
		private var intervalTime : int;

		public function GameManager()
		{
		}

		public static function getInstance() : GameManager
		{
			if (instance == null)
			{
				instance = new GameManager();
			}
			return instance;
		}

		/**
		 * 必须初始化
		 * @param stage
		 *
		 */
		public function init(stage : DisplayObjectContainer) : void
		{
			this.container = stage;
			this.runTime = getTimer();
			renderMgr = RenderManager.getInstance(stage)
			notify = GameEventDispatcher.getInstance();
			notify.addEventListener(GameEventType.ADD_GAME_UPDATE, addUpdateHandler);
			notify.addEventListener(GameEventType.DEL_GAME_UPDATE, delUpdateHandler);
		}

		public function start() : void
		{
			container.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		public function stop() : void
		{
			container.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			notify.removeEventListener(GameEventType.ADD_GAME_UPDATE, addUpdateHandler);
			notify.removeEventListener(GameEventType.DEL_GAME_UPDATE, delUpdateHandler);
		}

		/**
		 * 帧频更新
		 * @param evt
		 *
		 */
		public function onEnterFrame(evt : Event) : void
		{
			intervalTime = getTimer() - runTime;
			runTime = getTimer();
			update(intervalTime);
			renderMgr.update(intervalTime);
		}

		/**
		 * 更新队列
		 * @param value
		 *
		 */
		public function update(value : int) : void
		{
			var i : int;
			var len : int = highUpdatables.length;

			for (i = len - 1; i >= 0; i -= 1)
			{
				if (highUpdatables[i] == null)
					continue;

				if (!highUpdatables[i].checkUpdatable(value) || lowUpdatables[i].isDestroy)
					continue;
				highUpdatables[i].update(value);
			}
			len = middenUpdatables.length;

			for (i = len - 1; i >= 0; i -= 1)
			{
				if (middenUpdatables[i] == null)
					continue;

				if (!middenUpdatables[i].checkUpdatable(value) || lowUpdatables[i].isDestroy)
					continue;
				middenUpdatables[i].update(value);
			}
			len = lowUpdatables.length;

			for (i = len - 1; i >= 0; i -= 1)
			{
				if (lowUpdatables[i] == null)
					continue;

				if (!lowUpdatables[i].checkUpdatable(value) || lowUpdatables[i].isDestroy)
					continue;
				lowUpdatables[i].update(value);
			}

		}

		/**
		 * 添加更新列表
		 * @param update   更新对象
		 * @param level    更新的等级,0低级,1中级,2高级
		 * @param priority 优先级
		 *
		 */
		public function addUpdateHandler(evt : GameEvent) : void
		{
			var update : IUpdate = evt.body as IUpdate;
			var updatableArray : Array;

			if (update == null)
				return;

			switch (update.registerdLevel)
			{
				case Update.PRIORITY_HIGH:
					updatableArray = highUpdatables;
					break;
				case Update.PRIORITY_MIDDEN:
					updatableArray = middenUpdatables;
					break;
				case Update.PRIORITY_LOW:
					updatableArray = lowUpdatables;
					break;
			}

			if (updatableArray == null)
				return;
			var index : int = updatableArray.indexOf(update);

			if (index != -1)
				return;
			update.priority = update.priority;
			updatableArray.push(update);
			updatableArray.sortOn("priority", Array.NUMERIC | Array.DESCENDING);
		}

		public function delUpdateHandler(evt : GameEvent) : void
		{
			var update : IUpdate = evt.body as IUpdate;
			var updatableArray : Array;

			if (update == null)
				return;

			switch (update.registerdLevel)
			{
				case Update.PRIORITY_HIGH:
					updatableArray = highUpdatables;
					break;
				case Update.PRIORITY_MIDDEN:
					updatableArray = middenUpdatables;
					break;

				case Update.PRIORITY_LOW:
					updatableArray = lowUpdatables;
					break;
			}

			if (updatableArray == null)
				return;
			var index : int = updatableArray.indexOf(update);

			if (index == -1)
				return;
			updatableArray.splice(index, 1);
			return;
		}

	}
}